结构：
	什么是结构：是一种程序员自己设计数据类型，由若干个不同的数据类型组成，可用于描述一个事物各项数据。
	
	1.设计结构(设计数据类型)：// 仅仅是一种数据类型
	typedef struct 结构名
	{
		类型1 成员名1;
		类型2 成员名2;
		类型3 成员名3;
		...
	}结构名;
	
	typedef struct Student
	{
		char name[20];
		char sex;
		short age;
		...
	}Student;
	
	2.定义结构变量：
		struct 结构名 结构变量名。
		Student stu;
		注意：struct关键字不能省略。
	
	3.访问成员：
		结构变量名.成员名；
		stu.name,stu.sex,stu.age
		
	
		
		
	初始化：结构变量与普通变量一样，默认值是不确定的。
		struct 结构名 结构变量名 ＝ {"hehe",'m',"销售"};
		注意：要按照成员的顺序初始化。
	初始化指定的成员:
		struct 结构名 结构变量名 ＝ {.成员名='f',.成员名＝"良辰"};
		注意：未初始化的成员默认为零。
	练习1：定义学生结构体（学号、姓名、性别、年龄、成绩），定义学生结构变量使用scanf赋值并显示。
	
typedef：类型重定义，可以给已有数据类型重定义一个简短的名字。
	struct 结构名是一种类型，typedef可以把他们两个重定义成一个单词的数据类型。
	注意：struct可以定义匿名结构，然后使用typedef对匿名结构重定义，但不建议这样。
	注意：typedef与#define不同，#define仅仅是内容替换而typedef是重新定义一个新的类型，比如：
	typedef int* intp; 
	#define intp int*
	
在堆内存中存储结构变量：
	struct Student* stup = malloc(sizeof(struct Student));
	使用结构指针访问成员名:
		结构指针->成员名；
		(*结构指针).成员名；


计算结构的字节数：
	注意：结构成员的顺序会影响结构的字节数，设计结构时合适的成员顺序可以尽可能的节约内存。
	结构的每个成员都有自己的存储空间，因此结构的字节数是所以成员的总和还要多。
	结构类型为了能够快速访问成员，会对成员的存储位置进行对齐和补齐。
	对齐：(假定每个结构都从零地址开始)每个成员存储的内存编号必须是它自己字节数的整数倍，如果不是整数倍则使用后面的内存（结构的成员之间可能会有一些空隙）。
	补齐：结构的字节必须是它最大成员的整数倍，如果不是则填充一些空字节。
	注意：在Linux系统下计算补齐和对齐时超出4字节的按4字节计算。
	
	作业：使用结构重写通讯录。
	
	struct 结构名
	{
		类型1 成员名1:n;
		类型2 成员名2:n;
		类型3 成员名3:n;
		...
	};
	// n指定成员的字节数
	
	
	
联合（共用）：union 它与结构的使用语法基本一样，区别是结构的每个成员都有独立的存储空间，而联合是所有成员共用一块存储空间（每个成员都从0地址开始），因此同一时刻只能有一个成员使用，只要有一个成员的值发生变化只它成员的值也会随之变化。
	注意：联合的特点就是使用少量的内存对应多个标识符，使用它可以节约内存，现在的编程中很少使用联合（不再需要极端的节约内存）。
	联合常考的知识点：
	1、计算大小，不需要计算对齐（每个成员都从零开始，天然对齐）但要注意补齐。
	2、利用联合判断系统的大小端。
		低地址存储低位数据，小端。
		低地址存储高位数据，大端。
		绝大多数的个人计算机都是小端，而服务器、网络设备都是大端（网络字节序）。
	
	
枚举：enum  一个个列举出来。
	枚举就相当于值受限的int类型，定义枚举就是把这种变量可以等于的值列举出来用一个标识符表示，除此之外再等于其它的值就是非法的（C语言中不检查，为了运行效率，而在C＋＋中会严格检查）。
	枚举值默认从零开始，逐渐加1，也可以指定。
	枚举值可以当常量使用（可以使用在case后,常与switch语句配合使用），可以用有意义的单词代表无意义的数字，可提高程序的可读性。
	枚举是一种锦上添花的技术，有它更好（提高安全性和可性），没有也行（使用int完全可以）。
	
多文件编程
	当代码过多时如果全写在一个.c文件中就会对代码的编写、阅读、调试造成干扰，为了更方便的管理代码，一般都按照功能把代码拆分成多个.c文件，为每个.c编写一个.h用于说明.c中有哪些函数、全局变量，然后分别编译每个.c（gcc -c code.c）生成目标文件，然后再把多个目标文件合并成一个可执行文件。
	注意：.c文件最好也包含对应的.h，因为这样可以防函数的声明与实现不符。	
	
头文件中应该写什么
	.h文件可能会被多个不同的.c包含，因此.h文件中的内存应该是可以多次被定义。
	1、函数声明
	2、全局变量声明（如果定义全局变量，不要初始化）。
	3、宏常量、宏函数
	4、结构、联合、枚举定义


==================================================================================================================
多文件编程
	
	如何进行多文件编程：根据功能、责任划分成若干个不同的.C文件，每个.c文件配备一个辅助文件.h，然后单独编译每个.c文件，生成目标文件.o，
	然后再把.o文件合并成一个可执行文件。
	
	头文件应该些什么：
		1、头文件卫士
		2、宏常量、宏函数
		3、结构、联合、枚举的设计
		4、变量、函数的声明
		5、static函数的实现
		
	

Makefile脚本
	把用于编译的命令记录到文件中。
	当多个文件程序时，编译会变得异常麻烦，而Makefile文件中可以把编译指令记录下来，当执行make命令时会自动把Makefile中的编译指令进行执行。
	使用make进行编译时会根据文件的修改时间来确定，.c文件是否需要再次编译，如果不是新修改的文件不需要重复编译。
	
	注意：
	必须使用tab键缩进，否则会产生 *** 遗漏分隔符 。
	
	
Makefile格式：
1、定义一些变量
CC=gcc
STD=-std=gnu99
BIN=a.out
OBJ=a.o main.o
FLAG=-Wall -Werror	
	-Wall 尽可能多的产生警告，以更严格的标准来检查代码。
	-Werror 把警告当作错误处理。
2、定义编译目标（函数）
目标名:其它目标（目标依赖，先执行其它目标，再执行此目标）
	指令 // 必须使用tab键缩进，否则会产生 *** 遗漏分隔符 。
	默认只执行排在第一个编译目标
	
3、用于清理目标文件的编译目标
clean:
	rm $(OBJ)

	
	
====================================================================================

GDB调试：
	1、设置ubuntu系统，当段错误时产生core
		ulimit	-c	unlimited
	
	2、编译时增加-g参数

	3、再次执行新编译的程序，重新产生core文件

	4.gdb a.out core 进行调试
		run/where
		





	
























